home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / dircnt.arc / DIRCNT.C next >
C/C++ Source or Header  |  1987-01-18  |  9KB  |  281 lines

  1. /*      
  2.     dircnt.c
  3.   This is a program to count the number of
  4.   folders on a drive or drives to see if we're below 
  5.   the awful 40 folder limit.Unlike the desktop it
  6.   does not use gemdos to access the directories
  7.   so that if we are over the limit running this shouldn't crash
  8.   the system.
  9.   David DeGeorge
  10.   princeton!idacrd!dld
  11.   ihnp4!acr011!dld
  12.   Jan 18,1987 
  13.   This is released to the Public Domain and of course I don't
  14.   claim it won't wreck anything and I'm not responsible
  15.   if it does.
  16. This will compile without change using the Mark Williams C compiler.
  17. Others may have to make minor changes
  18.  
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <osbind.h>
  23. /* dir.h structure of directory entries from the IBM manual */
  24. struct dir {
  25.         unsigned char     name[11];
  26.     unsigned char   attr ;
  27.     unsigned char   reserv[10];
  28.     unsigned int   crhms;      /* create time hours min seconds */
  29.     unsigned int   crmymd;      /* create time year mon day */
  30.     unsigned int   clustst;    /* cluster start */
  31.     unsigned long  len;        /* file length */
  32. };
  33. /* nota bene clustst and len are given in 8086 format so bytes and words
  34.  have to be reversed using the routines conv86w and lfix */
  35.     
  36. typedef struct dir DIR;
  37. /* from Mark Williams manual */
  38. struct BPB_ {
  39.     short bp_secsize; /* Sector size bytes */
  40.     short bp_clulen; /* Cluster size sectors */
  41.     short bp_clusize; /* Cluster size bytes */
  42.     short bp_dirlen; /* Directory length sectors */
  43.     short bp_fatlen; /* FAT length sectors */
  44.     short bp_fatsect;/* Second FAT sector number */
  45.     short bp_datsect; /* First data sector */
  46.     short bp_clusters; /* Number of clusters on the disk */
  47.     short bp_flags;
  48. };
  49. typedef struct BPB_ BPB;
  50.  
  51.  
  52.  
  53.  
  54. /* globals */
  55.  
  56. int *nufat;         /* will hold the FAT table */
  57. int *rootbuff;      /* will hold the buffer for the root directory */
  58. int dirnum=0;       /* number of directories */
  59. int recd= 0;        /* recursion depth */
  60. BPB *bpb;           /* ptr to current disk parameter block */
  61. unsigned int disk;  /* current disk */
  62. unsigned int endclust[]={ 0xff8,0xffff};   /* last cluster values */
  63.  
  64. /* Directories are read recursively up to 16 deep ( will this ever happen?)
  65.  since the cluster buffer is 1K we need a pretty big stack.
  66.  */
  67. long _stksize = 20000L;    
  68.  
  69.  
  70. main(argc,argv)
  71. char **argv ;
  72. {      
  73.         int size;
  74.         unsigned int nextclst();
  75.         int rootlen,rootst,i,j;
  76.         int atemp,tot;
  77.         DIR *root;
  78.         DIR sdir;
  79.         int drlist[16],numdr;
  80.         long drvmask;
  81.         
  82.         tot=0;
  83.         numdr=0; 
  84.         drvmask=Drvmap();  /* which drives are installed ? */
  85.  
  86.  if ( argc > 1){     /* use the arguments */
  87.                for ( i = 1 ; i < argc ; i++ ){
  88.                atemp=toupper(argv[i][0])-'A';   /* check the drive
  89.                                                 is installed  */
  90.                 if ( ( drvmask >> atemp) & 1){
  91.                  drlist[i-1]=atemp;
  92.                 numdr++;
  93.             }
  94.             else
  95.                        printf("Drive  %c is not installed\n",argv[i][0]);
  96.                }
  97.           }
  98.     else        /* no arguments just do the hard drive */ 
  99.             {
  100.             atemp = drvmask >> 2 ;  /* start at drive C and
  101.                                     go up consecutively */
  102.             i=0;
  103.             while ( atemp & 1 ) {
  104.                 drlist[i]=i+2;
  105.                 numdr++;
  106.                 atemp >>= 1;
  107.                 i++;
  108.            }                 
  109. }
  110.  
  111. /* Now we have a list of drives  to do */
  112.  
  113.   for ( i=0 ; i < numdr ;i++){           /*  main loop */
  114.          dirnum=0;         
  115.          disk = drlist[i];
  116.           bpb = ( BPB *) Getbpb(disk);  /* get disk info */
  117.            size = bpb ->bp_fatlen;      /* fatlen in sectors */      
  118.            if ( i > 0 )free(nufat);
  119.            nufat = (int *)malloc(size*(bpb -> bp_secsize));
  120.            if ( nufat == ( int *) 0 ) {
  121.            printf("Can't malloc space for the FAT table\n");
  122.             exit(1);
  123.         }
  124.         
  125.          if(Rwabs(0,nufat,size,1,disk) < 0L )diskerr();  /* read in fat table */
  126.          if ( i > 0) free( rootbuff);
  127.          rootbuff = ( int *) malloc( (bpb->bp_dirlen)*512 );
  128.          if ( rootbuff == (int * ) 0 ) {
  129.              printf("Can't malloc space for root directory\n");
  130.              exit(1);
  131.         }
  132.  
  133.          /* read in the root directory */ 
  134.                  
  135.          rootst = bpb->bp_fatsect + bpb->bp_fatlen;
  136.          /* starting sector of the root */
  137.          
  138.          if(Rwabs(0,rootbuff,bpb->bp_dirlen,rootst,disk) < 0L)diskerr();
  139.  
  140.          /* rootlen is how many possible root directory entries */
  141.          rootlen =((bpb -> bp_secsize)/sizeof(DIR))* bpb->bp_dirlen;
  142.  
  143.          root = ( DIR * )rootbuff;
  144.          
  145.          dirnum++;  /* count the root */
  146.          for ( j =0 ; j < rootlen ; j++) {
  147.  
  148.              sdir = root[j] ;   /* current entry */
  149.              
  150.              if( sdir.name[0] == '\0' ) goto bye; /* end of space ever 
  151.                                                   allocated */
  152.  
  153.          if (  sdir.attr &  0x10 ) { /* is it a directory */
  154.              if(sdir.name[0] == 0xE5 ) continue;  /* erased */
  155.                 if (sdir.name[0]=='.')   continue;  /* ignore . and .. */
  156.                 recd++;  /* increment recursion counter,
  157.                           convert cluster start
  158.                          to a 68000 integer, and read directory
  159.                          */
  160.                  readdir(conv86w(sdir.clustst)); 
  161. }
  162.  
  163. }
  164. bye:  
  165. tot += dirnum;   /* increment total */
  166. printf("The total number of directories on drive %c is  %d\n",'A'+disk,dirnum);
  167. }  
  168.      printf("The total number of directories counted is %d\n",tot);
  169.      printf("[RETURN]");getchar();   /* wait for a character */
  170.     
  171. }
  172.              
  173.              
  174. unsigned nextclst(clst)  /* returns the next cluster number as 68000 int */
  175. unsigned int clst;
  176.   {   
  177.      if(bpb -> bp_flags)return( conv86w(nufat[clst])); /* hard disk
  178.                                                       16 bit FAT */
  179.     else
  180.                    /*  floppy disk
  181.                        12 bit FAT 
  182.                    */
  183.         {     
  184.              unsigned int temp1,temp2;
  185.              char *p,*q;
  186.                 temp1 = clst + ( clst >> 1);  /* 1.5 * clst */
  187.                 /* this next funny stuff is to access nufat
  188.                  by byte offset. Since nufat is an array of ints
  189.                  to word align it and make it easier to access in
  190.                  the hard disk case we are paying now.
  191.                  */
  192.             q =( char *)nufat + temp1 ;
  193.             p= (char *)&temp2;
  194.             *p=*q;
  195.             *(p+1)=*(q+1);
  196.             temp2 = conv86w(temp2);
  197.             
  198. /* if clst is even take the  bottom order twelve bits
  199.   if clst is odd take the top order 12 bits. This
  200.   is straight from the IBM-PC manual
  201.   */        
  202.             if (!( clst & 1) ) return( 0xFFF & temp2); 
  203.               else return ( 0xFFF & ( temp2 >> 4 ));
  204.             }
  205. }    
  206.  
  207.  
  208. long lfix(j)  /* make an 8086 long int a 68000 long int */
  209. long j;       /* swap the hi-lo words and the bytes within the words */
  210. {
  211.     long temp1,temp2;
  212.     int *k,*l;
  213.         temp1 = j;
  214.          k= (int *)&temp1;
  215.          l=(int *)&temp2;      
  216.          *(l+1)= conv86w(*k);
  217.          *l    = conv86w(*(k+1));
  218.          return(temp2);
  219. }
  220.  
  221.  
  222. conv86w(i)   /* swap bytes  this is in MWC library but included */
  223. {              /* for completeness */
  224.     char *p,*q;
  225.     int k,j;
  226.     k=i;
  227.     p=(char *)&k;
  228.     q=(char *)&j;
  229.     *q = *( p+1);
  230.     *(q+1) = *(p);
  231.     return(j);
  232. }
  233.   
  234. readdir(clust)  /* readin a directory given the starting cluster */
  235. {
  236.     int buff[512]; /* for all our supposed portability this is */
  237.     int i;         /* the size of a cluster can't malloc 'cause */
  238.     DIR *dptr;    /* we want it on the stack so we can be recursive */
  239.     DIR sdir;
  240.     int dirl;
  241.     dirl = (bpb->bp_clusize)/sizeof(DIR);/* how many dir ents in cluster */
  242.       dirnum++ ;     /* increment global counter */
  243.         do {
  244.             dptr=( DIR *)buff;
  245.             reclst(buff,clust);   /* read cluster into buffer */
  246.                 for ( i=0 ; i < dirl ; i++) {
  247.                     sdir = dptr[i];
  248.                        if